package com.ojoin.trade.common_core.web.controller;
 
import java.io.IOException;
import java.net.URLEncoder;
import java.security.interfaces.RSAPublicKey;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
import org.apache.shiro.web.util.SavedRequest;
import org.apache.shiro.web.util.WebUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.ojoin.trade.common.Constants;
import com.ojoin.trade.common.constdef.IConstDef;
import com.ojoin.trade.common.exception.ControllerException;
import com.ojoin.trade.common.utils.CommonUtils;
import com.ojoin.trade.common.utils.Config;
import com.ojoin.trade.common.utils.LogUtils;
import com.ojoin.trade.common.web.controller.SimpleBaseController;
import com.ojoin.trade.common.web.domain.Result;
import com.ojoin.trade.common.web.domain.Result.Status;
import com.ojoin.trade.common.web.domain.SessionUser;
import com.ojoin.trade.common.web.service.IRSAService;
import com.ojoin.trade.common.web.shiro.Principal;
import com.ojoin.trade.common.web.shiro.session.SessionDAO;


/**
 * 登录
 */
@Controller
public class LoginUserController extends SimpleBaseController {

	private final Logger logger = LoggerFactory.getLogger(getClass());
	
	
	private final String succ_ipaynow_Url=Config.getProperty("succ.ipaynow.url");
	private final String succ_factor_Url=Config.getProperty("succ.factor.url");
	
	private final String login_ipaynow_Url=Config.getProperty("login.ipaynow.url");
	private final String login_factor_Url=Config.getProperty("login.factor.url");
	
	
	@Autowired
	private SessionDAO sessionDAO;
	
    
	@Autowired
	private IRSAService rsaSrv;
	
	@ResponseBody
	@RequestMapping(value = "/initcfg", method = RequestMethod.GET)
	public Map<String, Object> initcfg(HttpServletRequest request) {
		Principal principal = CommonUtils.getPrincipal();

		Map<String, Object> modelMap = new HashMap<String, Object>();
		RSAPublicKey pkey = rsaSrv.getDefaultPublicKey();
		if (null == pkey)
			throw new ControllerException("无法获取初始化参数");

		String modulus = rsaSrv.encodeHex(pkey.getModulus());
		String exponent = rsaSrv.encodeHex(pkey.getPublicExponent());
		// 获取生成的指定系数与指数
		modelMap.put("modulus", modulus);
		modelMap.put("exponent", exponent);
		
		Session session=CommonUtils.getSession();
		if (null != principal&&null!=session) {
			SessionUser user=(SessionUser)session.getAttribute(Constants.SESSION_LOGINUSER);
			modelMap.put(Constants.SESSION_LOGINUSER, user);
		}
		return modelMap;

	}
	
	/**
	 * 管理登录
	 * @throws IOException 
	 */
	@RequestMapping(value = "/login", method = RequestMethod.GET)
	public void login(HttpServletRequest request, HttpServletResponse response, Model model) throws IOException {
		Principal principal = CommonUtils.getPrincipal();
		SavedRequest beforeLogin=WebUtils.getAndClearSavedRequest(request);
		
		
		String succ_Url="";
		String login_Url="";
		
		if(null!=beforeLogin&&StringUtils.indexOfAny(beforeLogin.getRequestURI(), new String[]{"/operate","/sys"})!=-1){
			succ_Url=succ_factor_Url;
			login_Url=login_factor_Url;
		}else{
			succ_Url=succ_ipaynow_Url;
			login_Url=login_ipaynow_Url;
		}
		
		if(CommonUtils.isAjaxRequest(request)){
			Result result=new Result(Status.ERROR,"nologin","<a href='/' class='tips_login'>您未登录或长时间未操作,请先登录</a>");
			CommonUtils.sendJOSNResponse(response, result);
		}else{
			// 如果已经登录，则跳转到首页
			if(principal != null){
				response.sendRedirect(succ_Url);
			}else{
				response.sendRedirect(login_Url);
			}
		}
	}

	
	/**
	 * 登录成功后
	 */
	@RequestMapping(value = "/loginsuccess", method = RequestMethod.GET)
	public String index(HttpServletRequest request, HttpServletResponse response, Model model) {
		Principal principal = CommonUtils.getPrincipal();
		String loginType = principal.getLoginType();
		
		
		String succ_Url="";
		if(IConstDef.loginType_IpayNow.equals(loginType)){
			succ_Url=succ_ipaynow_Url;
		}else if(IConstDef.loginType_Factor.equals(loginType)){
			succ_Url=succ_factor_Url;
		}else{
			succ_Url=succ_ipaynow_Url;
		}
		
		return "redirect:"+succ_Url;
		 
	}
	
	/**
	 * 登录失败，登录的POST请求由Filter完成
	 * @throws IOException 
	 */
	@RequestMapping(value = "/login", method = RequestMethod.POST)
	public void loginFail(HttpServletRequest request, HttpServletResponse response) throws IOException {
		Principal principal = CommonUtils.getPrincipal();
		String loginType = request.getParameter(IConstDef.loginTypeParamKey);
		String message =null;
		//已经登录其他站点，又登录当前站点
		Subject subject = CommonUtils.getSubject();
        if (subject != null && subject.isAuthenticated()) {
        	if(!loginType.equals(principal.getLoginType())){
        		subject.logout();
                message=String.format("您已经登录%s，请重试！",principal.getLoginType().equals(IConstDef.loginType_IpayNow)?"九盈":"保理系统");
                principal=null;
        	}else{
        		message="AlreadyOnLine";
        	}
            
        }
		
		String succ_Url="";
		String login_Url="";
		if(IConstDef.loginType_IpayNow.equals(loginType)){
			succ_Url=succ_ipaynow_Url;
			login_Url=login_ipaynow_Url;
		}else if(IConstDef.loginType_Factor.equals(loginType)){
			succ_Url=succ_factor_Url;
			login_Url=login_factor_Url;
		}else{
			succ_Url=succ_ipaynow_Url;
			login_Url=login_ipaynow_Url;
		}
		
		//登录失败了 提取错误消息
        Exception shiroLoginFailureEx =
                (Exception) request.getAttribute(FormAuthenticationFilter.DEFAULT_ERROR_KEY_ATTRIBUTE_NAME);
        if (null==message&&shiroLoginFailureEx != null) {
        	String className = shiroLoginFailureEx.getClass().getName();
    		if (IncorrectCredentialsException.class.getName().equals(className)
    				/*|| UnknownAccountException.class.getName().equals(className)*/){
    			message = "用户或密码错误，请重试！";
    		} else if (shiroLoginFailureEx.getMessage() != null && StringUtils.startsWith(shiroLoginFailureEx.getMessage(), "prefix:")){
    			message = StringUtils.replace(shiroLoginFailureEx.getMessage(), "prefix:", "");
    		} else{
    			message = "系统异常，请稍后再试！";
    			LogUtils.error(logger, shiroLoginFailureEx,message);
    		}
        }
        
		if (StringUtils.isBlank(message) || StringUtils.equals(message, "null")){
			message = "系统异常，请稍后再试！";
		}
		
		
		LogUtils.info(logger, "login fail, active session size: %d, message: %s", 
				sessionDAO.getActiveSessions(false).size(), message);
		
		if(CommonUtils.isAjaxRequest(request)){
			Result result=new Result(false,message);
			CommonUtils.sendJOSNResponse(response, result);
		}else{
			//如果已经登录，则跳转到首页
			if(principal != null){
				response.sendRedirect(succ_Url+"?msg="+URLEncoder.encode(message,Constants.ENCODING));
			}else{
				response.sendRedirect(login_Url+"?msg="+URLEncoder.encode(message,Constants.ENCODING));
			}
		}
	}

}
